﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Astronaut.Bot;
using Astronaut.D3;
using Astronaut.Scripts.Common;

namespace Astronaut.Scripts.Monk
{
    /// <summary>
    /// 职业脚本核心类
    /// </summary>
    public class Core : GlobalBaseBotState
    {
        protected override void DoEnter(D3Player Entity)
        {
            base.DoEnter(Entity);
            base.combatState = new Monk.CombatState();
            Monk.CombatState.Output("武僧职业脚本启动");
        }
    }

    /// <summary>
    /// 技能类
    /// </summary>
    public class Ability
    {
        /// <summary>
        /// 技能ID
        /// </summary>
        public string SpellID { get; set; }

        /// <summary>
        /// 精气
        /// </summary>
        public int Spirit { get; set; }

        /// <summary>
        /// 技能是否需要按住不放
        /// </summary>
        public bool IsHold { get; set; }

        /// <summary>
        /// 雕文名称
        /// </summary>
        public string RuneName { get; set; }
    }

    /// <summary>
    /// 战斗状态类 Ver 1.1
    /// 目标选择部分修改了近战范围的怪，以怪物等级为最高优先。
    /// 目标选择部分新增了延迟攻击目标，当搜怪范围内只剩下延迟攻击目标后，才会攻击该目标
    /// </summary>
    public class CombatState : Common.CombatState
    {

        #region 属性和定义

        /// <summary>
        /// 是否处理BOSS战斗
        /// </summary>
        private static bool isHandleBossFight = false;

        /// <summary>
        /// 战斗耗时计时器
        /// </summary>
        private static Stopwatch battleTimeWatcher = new Stopwatch();

        /// <summary>
        /// 目标线程
        /// </summary>
        private static Thread targetThread;

        /// <summary>
        /// 目标线程计时器
        /// </summary>
        private static CWSpellTimer targetTimer = new CWSpellTimer(300);

        /// <summary>
        /// 检查掉血率线程
        /// </summary>
        private static Thread checkHpLostRateThread;

        /// <summary>
        /// 安全点线程
        /// </summary>
        private static Thread safeSpotThread;

        /// <summary>
        /// 安全点线程计时器
        /// </summary>
        private static CWSpellTimer safeSpotTimer = new CWSpellTimer(1000);

        /// <summary>
        /// 特殊攻击目标词典
        /// </summary>
        private static Dictionary<string, int> specialAttackTargetDictionary;

        /// <summary>
        /// 延迟攻击目标词典
        /// </summary>
        private static Dictionary<string, int> ignoreAttackTargetDictionary;

        /// <summary>
        /// 战斗总时长（毫秒）
        /// </summary>
        private static long battleTimer = 0;

        /// <summary>
        /// 是否开启调试信息
        /// </summary>
        private static bool isDebug = false;

        /// <summary>
        /// 拾取距离
        /// </summary>
        private static float getItemRange = 5;

        /// <summary>
        /// 掉血速率阈值
        /// </summary>
        private static int hpLostRate = 10000;

        /// <summary>
        /// 技能列表
        /// </summary>
        private static Dictionary<string, Ability> abilityDictionary;

        /// <summary>
        /// 使用回天的HP百分比
        /// </summary>
        private static int hpPct_BreathOfHeaven = 80;

        /// <summary>
        /// 找血球的HP百分比
        /// </summary>
        private static int hpPct_FindBloodBall = 60;

        /// <summary>
        /// 使用红药的HP百分比
        /// </summary>
        private static int hpPct_Potion = 40;

        /// <summary>
        /// 使用无敌的HP百分比
        /// </summary>
        private static int hpPct_Serenity = 30;

        /// <summary>
        /// 攻击距离
        /// </summary>
        private static int meleeRange = 15;

        /// <summary>
        /// 寻找怪物距离
        /// </summary>
        private static int patrolRange = 65;

        /// <summary>
        /// 释放技能间隔毫秒
        /// </summary>
        private static int skillInterval = 100;

        /// <summary>
        /// 逃跑时间间隔
        /// </summary>
        private static CWSpellTimer moveBackTimer = new CWSpellTimer(3000);

        /// <summary>
        /// 是否躲避AOE
        /// </summary>
        private static bool isAOEavoid = false;


        /// <summary>
        /// 安全点坐标
        /// </summary>
        private static Vector3D safeSpot;

        #endregion

        #region 参数初始化

        /// <summary>
        /// 设置技能词典
        /// </summary>
        private static void SetAbilityDictionary()
        {
            if (abilityDictionary == null)
            {
                abilityDictionary = new Dictionary<string, Ability>();

                Ability ability = new Ability();
                ability.SpellID = "Blinding Flash";
                ability.Spirit = 10;
                abilityDictionary.Add("炫目神光", ability);

                ability = new Ability();
                ability.SpellID = "Lashing Tail Kick";
                ability.Spirit = 30;
                abilityDictionary.Add("云龙摆尾", ability);

                ability = new Ability();
                ability.SpellID = "Exploding Palm";
                ability.Spirit = 40;
                abilityDictionary.Add("爆裂掌", ability);

                ability = new Ability();
                ability.SpellID = "Dashing Strike";
                ability.Spirit = 25;
                ability.IsHold = true;
                abilityDictionary.Add("暴风奔袭", ability);

                ability = new Ability();
                ability.SpellID = "Tempest Rush";
                ability.Spirit = 25;
                ability.IsHold = true;
                abilityDictionary.Add("瞬影打", ability);

                ability = new Ability();
                ability.SpellID = "Wave of Light";
                ability.Spirit = 75;
                abilityDictionary.Add("金钟罩", ability);

                ability = new Ability();
                ability.SpellID = "Breath of Heaven";
                ability.Spirit = 25;
                ability.RuneName = "Blazing Wrath";
                abilityDictionary.Add("回天气绝", ability);

                ability = new Ability();
                ability.SpellID = "Serenity";
                ability.Spirit = 10;
                abilityDictionary.Add("明镜止水", ability);

                ability = new Ability();
                ability.SpellID = "Inner Sanctuary";
                ability.Spirit = 30;
                abilityDictionary.Add("", ability);

                ability = new Ability();
                ability.SpellID = "Sweeping Wind";
                ability.Spirit = 5;
                ability.RuneName = "Sweeping Wind";
                abilityDictionary.Add("劲风煞", ability);

                ability = new Ability();
                ability.SpellID = "Mystic Ally";
                ability.Spirit = 25;
                abilityDictionary.Add("天地元灵", ability);

                ability = new Ability();
                ability.SpellID = "Mantra of Evasion";
                ability.Spirit = 50;
                ability.RuneName = "Mantra of Evasion";
                abilityDictionary.Add("回避真言", ability);

                ability = new Ability();
                ability.SpellID = "Mantra of Retribution";
                ability.Spirit = 50;
                abilityDictionary.Add("惩戒真言", ability);

                ability = new Ability();
                ability.SpellID = "Mantra of Healing";
                ability.Spirit = 50;
                abilityDictionary.Add("治疗真言", ability);

                ability = new Ability();
                ability.SpellID = "Mantra of Conviction";
                ability.Spirit = 50;
                ability.RuneName = "Mantra of Conviction";
                abilityDictionary.Add("定罪真言", ability);

                ability = new Ability();
                ability.SpellID = "Seven-Sided Strike";
                ability.Spirit = 50;
                abilityDictionary.Add("七星闪", ability);

                ability = new Ability();
                ability.SpellID = "Cyclone Strike";
                ability.Spirit = 50;
                abilityDictionary.Add("飓风转", ability);

                ability = new Ability();
                ability.SpellID = "Fists of Thunder";
                ability.Spirit = 0;
                abilityDictionary.Add("奔雷拳", ability);
            }
        }

        /// <summary>
        /// 设置特殊攻击目标词典
        /// </summary>
        private static void SetSpecialAttackTargetDictionary()
        {
            if (specialAttackTargetDictionary == null)
            {
                specialAttackTargetDictionary = new Dictionary<string, int>();
                specialAttackTargetDictionary.Add("沉沦魔炸弹狂", 4095);
            }
        }

        /// <summary>
        /// 设置延迟攻击目标词典
        /// </summary>
        private static void SetLazyAttackTargetDictionary()
        {
            if (ignoreAttackTargetDictionary == null)
            {
                ignoreAttackTargetDictionary = new Dictionary<string, int>();
                ignoreAttackTargetDictionary.Add("烈火食尸鬼", 144315);
            }
        }

        #endregion

        #region 释放技能

        /// <summary>
        /// 释放武僧目标类技能
        /// </summary>
        /// <param name="spellID"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private static bool CastMonkTargetSpell(Ability ability, D3Object target)
        {
            return (D3Control.CastTargetSpell(ability.SpellID, target));
        }

        /// <summary>
        /// 释放武僧方向类技能
        /// </summary>
        /// <param name="spellID"></param>
        /// <param name="loc"></param>
        /// <returns></returns>
        private static bool CastMonkDirectionSpell(Ability ability, Vector3D loc, int baseSpirit = 0)
        {
            return IsEnoughResourceForSpell(ability.SpellID, ability.Spirit, baseSpirit) ? (D3Control.CastDirectionSpell(ability.SpellID, loc)) : false;
        }

        /// <summary>
        /// 释放武僧位置类技能
        /// </summary>
        /// <param name="spellID"></param>
        /// <param name="loc"></param>
        /// <returns></returns>
        private static bool CastMonkLocationSpell(Ability ability, Vector3D loc, int baseSpirit = 0)
        {
            return IsEnoughResourceForSpell(ability.SpellID, ability.Spirit, baseSpirit) ? (D3Control.CastLocationSpell(ability.SpellID, loc, ability.IsHold))
: false;
        }

        /// <summary>
        /// 判断是否有足够的精气释放技能
        /// </summary>
        /// <returns></returns>
        private static bool IsEnoughResourceForSpell(string spellID, int spirit, int baseSpirit)
        {
            return (D3Control.canCast(spellID) && D3Control.Player.Spirit >= (spirit + baseSpirit));
        }

        #endregion

        #region 目标相关

        /// <summary>
        /// 目标路径是否可直接攻击
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private static bool IsPathCanMoveTo(D3Unit target)
        {
            var distance = D3Control.Player.Location.GetDistanceTo(target.Location, false);
            Output("distance:" + distance.ToString());
            Output("playerlocation:" + D3Control.Player.Location.X + "|" + D3Control.Player.Location.Y);

            bool canAttack = false;
            try
            {
                for (var i = 0; i < distance; i = i + 5)
                {
                    var sideSpot = D3Control.getSideSpot(D3Control.Player.Location, target.Location, i);
                    Output("sideSpot:" + sideSpot.X + "|" + sideSpot.Y);
                    if (!D3Control.LOS(sideSpot))
                    {
                        canAttack = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Output(ex.StackTrace + "|" + ex.Message);
            }
            Output("canattack:" + canAttack.ToString());
            Output("targetLocation:" + target.Location.X + "|" + target.Location.Y);
            return canAttack;
        }

        /// <summary>
        /// 获取目标
        /// </summary>
        private static bool GetTarget()
        {
            var meleeTargets = D3Control.TargetManager.GetAroundEnemy(meleeRange).OrderByDescending(t => t.MLevel).ToList();
            var targets = D3Control.TargetManager.GetAroundEnemy(patrolRange).OrderByDescending(t => t.MLevel).OrderBy(t => t.DistanceFromPlayer).ToList();
            var target = FindPriorityAttackTarget(targets);

            if (target != null)
            {
                target = IsPathCanMoveTo(target) ? target : null;
            }

            if (target != null)
            {
                D3Control.TargetManager.ClearTarget();
                D3Control.TargetManager.SetAttackTarget(target);
                return true;
            }
            else
            {
                bool isLazyAttackTarget = IsLazyAttackTarget(targets);
                Output(isLazyAttackTarget.ToString());
                if (!isLazyAttackTarget)
                {
                    target = meleeTargets.Find(t =>
                    {
                        if (D3Control.isObjectValid(t) && !t.IsDead && !D3Control.LOS(t.Location))
                        {
                            return true;
                        }
                        return false;
                    });
                    if (target != null)
                    {
                        target = IsPathCanMoveTo(target) ? target : null;
                    }

                    if (target == null)
                    {
                        target = targets.Find(t =>
                        {
                            if (D3Control.isObjectValid(t) && !t.IsDead && !D3Control.LOS(t.Location))
                            {
                                return true;
                            }
                            return false;
                        });
                        if (target != null)
                        {
                            target = IsPathCanMoveTo(target) ? target : null;
                        }
                    }
                }
                else
                {
                    target = meleeTargets.SkipWhile(t =>
                    {
                        foreach (var key in ignoreAttackTargetDictionary)
                        {
                            if (key.Value == t.ID)
                            {
                                return true;
                            }
                        }
                        return false;
                    }).ToList().Find(t =>
                    {
                        if (D3Control.isObjectValid(t) && !t.IsDead && !D3Control.LOS(t.Location))
                        {
                            return true;
                        }
                        return false;
                    });

                    if (target != null)
                    {
                        target = IsPathCanMoveTo(target) ? target : null;
                    }

                    if (target == null)
                    {
                        target = targets.SkipWhile(t =>
                        {
                            foreach (var key in ignoreAttackTargetDictionary)
                            {
                                if (key.Value == t.ID)
                                {
                                    return true;
                                }
                            }
                            return false;
                        }).ToList().Find(t =>
                        {
                            if (D3Control.isObjectValid(t) && !t.IsDead && !D3Control.LOS(t.Location))
                            {
                                return true;
                            }
                            return false;
                        });

                        if (target != null)
                        {
                            target = IsPathCanMoveTo(target) ? target : null;
                        }
                    }
                }

                if (target != null)
                {
                    D3Control.TargetManager.ClearTarget();
                    D3Control.TargetManager.SetAttackTarget(target);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 是否延迟攻击目标
        /// </summary>
        /// <param name="targets"></param>
        /// <returns></returns>
        private static bool IsLazyAttackTarget(List<D3Unit> targets)
        {
            return targets.SkipWhile(t =>
            {
                foreach (var key in ignoreAttackTargetDictionary)
                {
                    if (key.Value == t.ID)
                    {
                        return true;
                    }
                }
                return false;
            }).Count() > 0;
        }

        /// <summary>
        /// 查找优先攻击目标
        /// </summary>
        /// <param name="targets"></param>
        /// <returns></returns>
        private static D3Unit FindPriorityAttackTarget(List<D3Unit> targets)
        {
            D3Unit specialTarget = null;
            string targetName = string.Empty;
            targets.ForEach(t =>
            {
                bool isExist = false;
                if (D3Control.isObjectValid(t) && !t.IsDead && !D3Control.LOS(t.Location) && D3Control.Player.Location.GetDistanceTo(t.Location, false) <= meleeRange)
                {
                    foreach (var target in specialAttackTargetDictionary)
                    {
                        if (t.ID == target.Value)
                        {
                            targetName = target.Key;
                            specialTarget = t;
                            isExist = true;
                            break;
                        }
                    }
                }
                if (isExist)
                {
                    Output("找到特殊目标：" + targetName);
                    return;
                }
            });

            return specialTarget;
        }

        #endregion

        #region 战斗中属性检查

        /// <summary>
        /// 检查Buff
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="abilityName"></param>
        /// <returns></returns>
        private static bool CheckBuff(D3Player entity, string abilityName)
        {
            if (!D3Control.HasBuff(abilityDictionary[abilityName].RuneName))
            {
                return CastMonkLocationSpell(abilityDictionary[abilityName], D3Control.Player.Location);
            }
            return true;
        }

        /// <summary>
        /// 检查玩家血量百分比
        /// </summary>
        private static void CheckPlayerHpPct()
        {
            var playerHpPct = D3Control.Player.HpPct;
            if (playerHpPct <= -100 || playerHpPct >= 100)
            {
                playerHpPct = 100;
            }

            if (playerHpPct < hpPct_BreathOfHeaven)
            {
                if (CastMonkLocationSpell(abilityDictionary["回天气绝"], D3Control.Player.Location))
                {
                    Output("血量为：" + playerHpPct.ToString() + "%， 使用回天气绝");
                }
            }
            if (playerHpPct < hpPct_FindBloodBall)
            {
                D3Object healthGlobe = D3Control.ClosestHealthGlobe;
                if (healthGlobe != null && healthGlobe.DistanceFromPlayer < meleeRange)
                {
                    D3Control.MoveTo(healthGlobe, 10f);
                    Output("血量为：" + playerHpPct.ToString() + "%， 吃血球");
                }
            }
            if (playerHpPct < hpPct_Potion)
            {
                D3Control.usePotion();
                Output("血量为：" + playerHpPct.ToString() + "%， 吃药");
            }
            if (playerHpPct < hpPct_Serenity)
            {
                if (CastMonkLocationSpell(abilityDictionary["明镜止水"], D3Control.Player.Location))
                {
                    Output("血量为：" + playerHpPct.ToString() + "%， 使用明镜止水");
                }
            }
        }

        #endregion

        #region 战斗相关

        /// <summary>
        /// 随机移动
        /// </summary>
        /// <returns></returns>
        private static bool MoveRandom()
        {
            var randomX = new Random(DateTime.Now.Millisecond);
            var x = randomX.Next(-10, 10);
            Thread.Sleep(50);
            var randomY = new Random(DateTime.Now.Millisecond);
            var y = randomY.Next(-10, 10);
            Thread.Sleep(50);
            var tmpLocation = D3Control.Player.Location.CloneVector();
            tmpLocation.X += x;
            tmpLocation.Y += y;
            if (!D3Control.LOS(tmpLocation))
            {
                D3Control.ClickMoveTo(tmpLocation);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 攻击怪
        /// </summary>
        private static void AttackEnemy()
        {
            bool checkBuffResult = false;
            if (CheckBuff(D3Control.Player, "劲风煞"))
            {
                if (CheckBuff(D3Control.Player, "定罪真言") || CheckBuff(D3Control.Player, "回避真言"))
                {
                    checkBuffResult = true;
                    CheckBuff(D3Control.Player, "回天气绝");
                }
            }
            for (int i = 0; i < 3; i++)
            {
                if (!CastMonkTargetSpell(abilityDictionary["奔雷拳"], D3Control.curTarget) || !D3Control.isObjectValid(D3Control.curTarget) || D3Control.curTarget.IsDead)
                {
                    break;
                }
                D3Control.Player.Wait(skillInterval);
            }
            if (checkBuffResult)
            {
                CastMonkDirectionSpell(abilityDictionary["炫目神光"], D3Control.Player.Location, abilityDictionary["回天气绝"].Spirit);
                CastMonkDirectionSpell(abilityDictionary["云龙摆尾"], D3Control.Player.Location, abilityDictionary["回天气绝"].Spirit);
                CastMonkDirectionSpell(abilityDictionary["金钟罩"], D3Control.Player.Location, abilityDictionary["回天气绝"].Spirit);
            }
            AvoidAOE();
        }

        /// <summary>
        /// 战斗中移动
        /// </summary>
        /// <returns></returns>
        private static bool MoveToStartFight()
        {
            if (!GlobalBaseBotState.checkBeforePull(D3Control.Player))
            {
                return false;
            }
            if (D3Control.getDoorInWay(D3Control.curTarget) != null)
            {
                D3Control.MoveTo(D3Control.curTarget, 2.5f);
                return false;
            }
            if (D3Control.isObjectValid(D3Control.curTarget) && !D3Control.curTarget.IsDead)
            {
                var targetRange = D3Control.Player.Location.GetDistanceTo(D3Control.curTarget.Location, false);
                if (targetRange > meleeRange || D3Control.LOS(D3Control.curTarget.Location))
                {
                    D3Control.MoveTo(D3Control.curTarget, 5f);
                    Output("怪物ID: " + D3Control.curTarget.ID.ToString() + " 距离：" + targetRange.ToString() + " 距离有点远了，走过去揍之");
                }
                else
                {
                    Output("怪物ID: " + D3Control.curTarget.ID.ToString() + " 距离：" + targetRange.ToString() + " 距离够近，揍之");
                }
            }
            return true;
        }

        /// <summary>
        /// 躲避AOE
        /// </summary>
        /// <returns></returns>
        private static void AvoidAOE()
        {
            if (isAOEavoid)
            {
                var dTargetInfo = D3Control.getDangourousTargetInfo();
                safeSpot = D3Control.getSafePoint(dTargetInfo);
                if (safeSpot != null)
                {
                    Output("检测到AOE，开始躲避");
                    DateTime start = DateTime.Now;
                    var distance = D3Control.Player.Location.GetDistanceTo(safeSpot, false);
                    D3Control.ClickMoveTo(safeSpot);
                    if (distance < 15)
                    {
                        Thread.Sleep((int)(distance * 1000 / D3Control.Player.speed));
                    }
                    else
                    {
                        D3Control.Player.waitTillNoMotion();

                    }
                    Output(string.Format("躲避耗时{0}毫秒", DateTime.Now.Subtract(start).TotalMilliseconds));
                }
                isAOEavoid = false;
            }
        }

        #endregion

        #region 线程

        /// <summary>
        /// 执行线程
        /// </summary>
        private static void RunThread()
        {
            if (checkHpLostRateThread == null || !checkHpLostRateThread.IsAlive)
            {
                checkHpLostRateThread = new Thread(new ThreadStart(SetCheckHpLostRateThreadMethod));
                checkHpLostRateThread.IsBackground = true;
                checkHpLostRateThread.Start();
            }
        }

        /// <summary>
        /// 设置检查血量掉率线程方法
        /// </summary>
        private static void SetCheckHpLostRateThreadMethod()
        {
            while (D3Control.IsInGame() && D3Control.Player.isInCombat)
            {
                if (!isAOEavoid)
                {
                    var hp1 = (int)D3Control.Player.Hp;
                    if (hp1 < 0 || hp1 >= (int)D3Control.Player.MaxHp)
                    {
                        hp1 = (int)D3Control.Player.MaxHp;
                    }
                    Thread.Sleep(300);
                    var hp2 = (int)D3Control.Player.Hp;
                    if (hp2 < 0 || hp2 >= (int)D3Control.Player.MaxHp)
                    {
                        hp2 = (int)D3Control.Player.MaxHp;
                    }
                    var tmpHpLostRate = hp2 - hp1;
                    if (tmpHpLostRate >= 0)
                        tmpHpLostRate = 0;
                    tmpHpLostRate = Math.Abs(tmpHpLostRate);
                    isAOEavoid = (tmpHpLostRate >= hpLostRate);
                    if (isAOEavoid)
                    {
                        Output(string.Format("血量掉率：{0}每秒，可以进行回避", tmpHpLostRate));
                    }
                }
                else
                {
                    Thread.Sleep(300);
                }
            }
        }

        #endregion

        #region 基类方法重写

        /// <summary>
        /// 重载基类初始化函数
        /// </summary>
        /// <param name="Entity"></param>
        protected override void DoEnter(D3Player Entity)
        {
            SetAbilityDictionary();
            SetSpecialAttackTargetDictionary();
            SetLazyAttackTargetDictionary();
        }

        /// <summary>
        /// 重载基类退出函数
        /// </summary>
        /// <param name="entity"></param>
        protected override void DoExit(D3Player entity)
        {
            if (PreviousState != null)
            {
                CallChangeStateEvent(entity, PreviousState, false, false);
            }
        }

        /// <summary>
        /// 重载基类完成函数
        /// </summary>
        /// <param name="entity"></param>
        protected override void DoFinish(D3Player entity)
        {
        }

        /// <summary>
        /// 重载基类战斗函数
        /// </summary>
        /// </summary>
        protected override void DoExecute(D3Player Entity)
        {

            //RunThread();

            battleTimeWatcher.Start();

            CWSpellTimer combatThresholdTimer = new CWSpellTimer(10 * 1000, false);
            CWSpellTimer waitTimer = new CWSpellTimer(1000);

            D3Control.checkLoots();
            CheckPlayerHpPct();
            GetTarget();

            while (D3Control.IsInGame() && !D3Control.Player.IsDead)
            {
                CheckPlayerHpPct();
                if (D3Control.Player.isBeingCCed())
                {
                    if (CastMonkLocationSpell(abilityDictionary["明镜止水"], D3Control.Player.Location))
                    {
                        Output("被定身了，使用明镜止水");
                    }
                }

                if (D3Control.isObjectValid(D3Control.curTarget) && !D3Control.curTarget.IsDead)
                {
                    waitTimer.Reset();
                    if (isHandleBossFight)
                        D3Control.TargetManager.handleSpecialFight();
                    if (MoveToStartFight())
                    {
                        AttackEnemy();
                    }
                }
                else
                {
                    if (waitTimer.IsReady && D3Control.Player.isInCombat)
                    {
                        waitTimer.Reset();
                        Output("附近已经没有敌人了，但是还在战斗状态，要么卡点了，要么有地底下的，天上飞的怪导致，进行随机小碎步移动，尝试离开战斗状态");
                        while (true)
                        {
                            if (MoveRandom())
                            {
                                break;
                            }
                        }
                    }
                }
                GetTarget();
                if (!D3Control.Player.isInCombat || combatThresholdTimer.IsReady)
                    break;
                Thread.Sleep(100);
            }
            battleTimeWatcher.Stop();
            TimeSpan ts = new TimeSpan(battleTimeWatcher.ElapsedTicks);
            Output(string.Format("战斗总时长：{0}天{1}时{2}分{3}秒", ts.Days, ts.Hours, ts.Minutes, ts.Seconds));
        }

        #endregion

        #region 其他

        /// <summary>
        /// 输出信息
        /// </summary>
        /// <param name="message"></param>
        public static void Output(string message)
        {
            if (isDebug)
            {
                D3Control.output(message);
            }
        }

        #endregion

    }
}